cmake_minimum_required(VERSION 3.15)
project(kwdb_ingest VERSION 1.0.0 LANGUAGES CXX)

# Find packages using pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(PROTOBUF REQUIRED protobuf)
pkg_check_modules(GRPC REQUIRED grpc++)

# Find tools - prefer system protoc to avoid version mismatch
# First try system locations to avoid anaconda/virtualenv versions
find_program(PROTOC protoc
    PATHS /usr/bin /usr/local/bin
    NO_DEFAULT_PATH)

if(NOT PROTOC)
    # Fall back to default search
    find_program(PROTOC protoc REQUIRED)
endif()

find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin
    PATHS /usr/bin /usr/local/bin
    NO_DEFAULT_PATH)

if(NOT GRPC_CPP_PLUGIN)
    # Fall back to default search
    find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin REQUIRED)
endif()

message(STATUS "Using protoc: ${PROTOC}")
message(STATUS "Using grpc_cpp_plugin: ${GRPC_CPP_PLUGIN}")

# Proto files location
# Always generate proto files in build directory to avoid version conflicts
message(STATUS "Generating proto files in build directory")
set(PROTO_OUTPUT_DIR ${CMAKE_BINARY_DIR}/generated)
file(MAKE_DIRECTORY ${PROTO_OUTPUT_DIR})

# Proto source file
set(PROTO_FILE ${CMAKE_SOURCE_DIR}/proto/ingest.proto)

# Generated files
set(PROTO_SRCS ${PROTO_OUTPUT_DIR}/ingest.pb.cc)
set(PROTO_HDRS ${PROTO_OUTPUT_DIR}/ingest.pb.h)
set(GRPC_SRCS ${PROTO_OUTPUT_DIR}/ingest.grpc.pb.cc)
set(GRPC_HDRS ${PROTO_OUTPUT_DIR}/ingest.grpc.pb.h)

# Custom command to generate proto files
add_custom_command(
    OUTPUT ${PROTO_SRCS} ${PROTO_HDRS} ${GRPC_SRCS} ${GRPC_HDRS}
    COMMAND ${PROTOC}
        --cpp_out=${PROTO_OUTPUT_DIR}
        --grpc_out=${PROTO_OUTPUT_DIR}
        --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN}
        -I${CMAKE_SOURCE_DIR}/proto
        ${PROTO_FILE}
    DEPENDS ${PROTO_FILE}
    COMMENT "Generating Protocol Buffer and gRPC files"
    VERBATIM
)

# Proto library
add_library(ingest_proto ${PROTO_SRCS} ${GRPC_SRCS})
target_include_directories(ingest_proto PUBLIC
    ${PROTO_OUTPUT_DIR}
    ${PROTOBUF_INCLUDE_DIRS}
    ${GRPC_INCLUDE_DIRS}
)
target_link_libraries(ingest_proto PUBLIC
    ${PROTOBUF_LIBRARIES}
    ${GRPC_LIBRARIES}
)

# Add SDK subdirectory
add_subdirectory(sdk-cpp)

# Add server subdirectory
option(BUILD_SERVER "Build ingestd server" ON)
if(BUILD_SERVER)
    add_subdirectory(server/ingestd)
endif()

# Add examples (optional)
option(BUILD_EXAMPLES "Build example programs" ON)
if(BUILD_EXAMPLES)
    add_subdirectory(examples/cpp)
endif()

# Add benchmarks (optional)
option(BUILD_BENCHMARKS "Build benchmark programs" ON)
if(BUILD_BENCHMARKS)
    add_subdirectory(bench)
endif()

# Add tests (optional)
option(BUILD_TESTS "Build test programs" ON)
if(BUILD_TESTS)
    add_subdirectory(test/cpp)
endif()

# Installation rules
# Install SDK headers
install(DIRECTORY ${CMAKE_SOURCE_DIR}/sdk-cpp/include/kwdb
        DESTINATION include)

# Install SDK library
install(TARGETS kwdb_sdk
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION bin)

# Install proto library (optional, for advanced users)
install(TARGETS ingest_proto
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib)
